package com.pig.easy.bpm.dubbo.filter;

import com.pig.easy.bpm.constant.BpmConstant;
import com.pig.easy.bpm.utils.SnowKeyGenUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * todo:
 *
 * @author : zhoulin.zhu
 * @date : 2021/1/8 16:05
 */
@Activate(group = {CommonConstants.CONSUMER, CommonConstants.PROVIDER})
public class GlobalTraceFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(GlobalTraceFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        logger.info("#########GlobalTraceFilter#######start###{}#{}###",invoker,invocation);
        RpcContext rpcContext = RpcContext.getContext();

        String traceId = invocation.getAttachment(BpmConstant.TRACE_ID);
        long startTime = System.currentTimeMillis();
        logger.info("###########start########{}:{}###########",traceId,rpcContext.isProviderSide()?"PROVIDER":"CONSUMER");

        if(!StringUtils.isBlank(traceId)) {
            RpcContext.getContext().setAttachment(BpmConstant.TRACE_ID,traceId);
        } else {
            RpcContext.getContext().setAttachment(BpmConstant.TRACE_ID, SnowKeyGenUtils.getInstance().getNextId());
        }

        if (rpcContext.isProviderSide()) {
            MDC.put(BpmConstant.TRACE_ID,traceId);
        }

        Result result = invoker.invoke(invocation);

        if (rpcContext.isProviderSide()) {
            MDC.remove(BpmConstant.TRACE_ID);
        }
        logger.info("###########end########{}:{}#######spendTime:{}####",traceId,rpcContext.isProviderSide()?"PROVIDER":"CONSUMER",System.currentTimeMillis()-startTime);

        return result;
    }
}
